package com.whccb.apps.office.document.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.actionsoft.bpms.bo.engine.BO;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.util.ConsolePrinter;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.bpms.util.UUIDGener;
import com.actionsoft.sdk.local.SDK;

public class ODFileNumUtil {

    private List<String> reserveList;
    private List<String> jumpList;

    public int getOfficeDocumentFileNum(String flag, String recordTypeId,
            String year) {
        StringBuffer queryMaxNumSql = new StringBuffer();
        queryMaxNumSql.append(
                " SELECT MAX(a.NUM) MAXNUM  FROM BO_WHBK_OD_FILENUM a ");
        queryMaxNumSql.append(" WHERE a.RECORDTYPEID = :RECORDTYPEID ");
        queryMaxNumSql.append(" AND a.YEAR = :YEAR AND a.FLAG = :FLAG ");
        queryMaxNumSql.append(
                " AND NOT EXISTS(SELECT * FROM BO_WHBK_OD_FNUM_RESERVE b WHERE a.RECORDTYPEID = b.RECORDTYPEID AND a.YEAR = b.YEAR AND a.NUM = b.FILENUM) ");
        queryMaxNumSql.append(
                " AND NOT EXISTS(SELECT * FROM BO_WHBK_OD_FNUM_JUMP b WHERE a.RECORDTYPEID = b.RECORDTYPEID AND a.YEAR = b.YEAR AND a.NUM = b.FILENUM) ");
        Map<String, Object> paraMap = new HashMap<String, Object>();
        paraMap.put("RECORDTYPEID", recordTypeId);
        paraMap.put("YEAR", year);
        paraMap.put("FLAG", flag);
        int maxNum = DBSql.getInt(queryMaxNumSql.toString(), "MAXNUM", paraMap);
        return getRightNum(maxNum + 1, recordTypeId, year, flag);
    }

    public boolean saveOfficeDocumentFileNum(String flag, String recordTypeId,
            String year, int fileNum, String refBindid, String refBo,
            String uid) {

        BO fileCheckBo = SDK.getBOAPI().getByKeyField("BO_WHBK_OD_FILENUM",
                "REFBINDID", refBindid);
        if (fileCheckBo != null) {
            List<BO> boList = SDK.getBOAPI().query("BO_WHBK_OD_FILENUM")
                    .addQuery("RECORDTYPEID =", recordTypeId)
                    .addQuery("YEAR =", year).addQuery("NUM =", fileNum)
                    .addQuery("FLAG =", flag)
                    .addQuery("ID !=", fileCheckBo.getId()).list();
            if (boList == null || boList.isEmpty() || boList.size() == 0) {// 可以执行更新操作
                // 执行更新
                fileCheckBo.setBindId("");
                fileCheckBo.set("RECORDTYPE", "");
                fileCheckBo.set("RECORDTYPEID", recordTypeId);
                fileCheckBo.set("YEAR", year);
                fileCheckBo.set("NUM", fileNum);
                fileCheckBo.set("FLAG", flag);
                fileCheckBo.set("REFBO", refBo);
                fileCheckBo.set("REFBINDID", refBindid);
                SDK.getBOAPI().update("BO_WHBK_OD_FILENUM", fileCheckBo);
                return true;
            } else {
                return false;
            }
        } else {
            List<BO> boList = SDK.getBOAPI().query("BO_WHBK_OD_FILENUM")
                    .addQuery("RECORDTYPEID =", recordTypeId)
                    .addQuery("YEAR =", year).addQuery("NUM =", fileNum)
                    .addQuery("FLAG =", flag).list();
            if (boList == null || boList.isEmpty() || boList.size() == 0) {// 可以执行插入操作
                // 执行新增
                fileCheckBo = new BO();
                fileCheckBo.setId(UUIDGener.getUUID());
                fileCheckBo.set("RECORDTYPE", "");
                fileCheckBo.set("RECORDTYPEID", recordTypeId);
                fileCheckBo.set("YEAR", year);
                fileCheckBo.set("NUM", fileNum);
                fileCheckBo.set("FLAG", flag);
                fileCheckBo.set("REFBO", refBo);
                fileCheckBo.set("REFBINDID", refBindid);
                SDK.getBOAPI().createDataBO("BO_WHBK_OD_FILENUM", fileCheckBo,
                        UserContext.fromUID(uid));
                return true;
            } else {
                return false;
            }
        }
    }

    private int getRightNum(int seed, String recordTypeId, String year,
            String flag) {
        // reserveList
        if (this.reserveList == null || this.reserveList.isEmpty()
                || this.reserveList.size() == 0) {
            this.reserveList = getOtherFileNum(recordTypeId, year, seed,
                    "BO_WHBK_OD_FNUM_RESERVE");// 预留号记录
        }
        ConsolePrinter.info("seed-----" + seed);
        ConsolePrinter.info("编号------" + (this.jumpList == null));

        // jumpList
        if (this.jumpList == null || this.jumpList.isEmpty()
                || this.jumpList.size() == 0) {
            this.jumpList = getOtherFileNum(recordTypeId, year, seed,
                    "BO_WHBK_OD_FNUM_JUMP");// 跳号记录
        }

        List<BO> boList = SDK.getBOAPI().query("BO_WHBK_OD_FILENUM")
                .addQuery("RECORDTYPEID =", recordTypeId)
                .addQuery("YEAR =", year).addQuery("FLAG =", flag)
                .addQuery("NUM =", seed).list();
        if (boList == null || boList.isEmpty() || boList.size() == 0) {
            if (this.reserveList == null && this.jumpList == null)
                return seed;
            if (isContain(this.jumpList, seed + "")
                    || isContain(this.reserveList, seed + ""))
                return getRightNum(seed + 1, recordTypeId, year, flag);
            else
                return seed;
        } else {
            return getRightNum(seed + 1, recordTypeId, year, flag);
        }
    }

    private boolean isContain(List<String> list, String matchStr) {
        if (list == null)
            return false;

        if (list.contains(matchStr))
            return true;
        else
            return false;
    }

    private List<String> getOtherFileNum(String recordTypeId, String year,
            int newNum, String boName) {
        List<BO> boList = SDK.getBOAPI().query(boName)
                .addQuery("RECORDTYPEID =", recordTypeId)
                .addQuery("YEAR =", year).addQuery("FILENUM >= ", newNum)
                .list();

        if (boList != null && !boList.isEmpty() && boList.size() > 0) {
            List<String> list = new ArrayList<String>();
            for (BO bo : boList) {
                if (bo != null
                        && StringUtils.isNotEmpty(bo.getString("FILENUM"))) {
                    list.add(bo.getString("FILENUM"));
                }
            }
            return list;
        }
        return null;
    }
}
